#ifndef _BITCASK_H
#define _BITCASK_H

#include <vector>
#include "Common.h"




class DataFile
{
public:
    u32 seq;
    u32 seq_history;
    u32 idx;
    int count;
    int key_size;
    int val_size;
    int garbage_count;
    int garbage_size;
};

class BtreeIndex;

class Bitcask
{
    friend class IdxSeqComparator;
public:
    int Init(const char *path, BtreeIndex *index);
    void Close();
    void Destroy();

    u64 Put(char *key, int key_size, char *val, int val_size, bool fsync = false);
    u64 Update(char *key, int key_size, char *val, int val_size, u64 old_pos, u32 old_size, bool fsync = false);
    int Get(char *val, int val_size, u64 pos);
    void Delete(char *key, int key_size, int val_size, u64 pos, bool fsync = false);
    void WriteOut();
private:
    static const int BUF_SIZE = 256 * KB;
    static const int FILESIZE_LIMIT = 64 * MB;
    static const int FILERECORD_LIMIT = 256 * KB;
    enum OP
    {
        INSERT = 0,
        UPDATE,
        DELETE,
    };

    static void* compact(void* instance);
    static void* aux_thread(void* instance);
    void fdisksync();
    int load_index();
    int recovery_from_df();
    void write_out();
    void compact_internal(u32 *idx_list, int count);

    char data_path[PATH_MAX];

    int buf_key_num;
    char *key_buf;
    u32 key_buf_pos;
    char *val_buf;
    u32 val_buf_pos;
    
    char *key_buf_swap;
    char *val_buf_swap;

    BtreeIndex *my_index;
    RWLock lock;

    std::vector<DataFile*> datafiles;
    u32 cur_seq;
    u32 cur_seq_history;
    u32 cur_idx;
    int cur_fd_key;
    int cur_fd_val;
    u32 df_num;
    bool is_running;
    int compact_status;

    pthread_t aux_tid, compact_tid;
};


#endif
